package com.onpositive.notes.parser;

import java.util.ArrayList;
import java.util.Map;

import com.onpositive.data.units.Unit;
import com.onpositive.units.ParsedDimension;
import com.onpositive.units.ParsedScalar;

public class DimensionParser extends AbstractParser{
	
	private static final long serialVersionUID = 5320061278660110648L;

	public DimensionParser() {
		super();
	}

	protected ArrayList<Block<ParsedDimension>> parseNonRangeValues(
			String str,
			int startIndex,
			int endIndex,
			int delimeterEnd,
			Map<String, Object> metaInfo,
			String comment )
	{
		ArrayList<Block<Double>> numBlockList = new ArrayList<Block<Double>>() ;
		
		Block<Double> lBlock ;
		int off = startIndex ;
		while(true){
			try{
				lBlock = lookNearestNumberFromStart( str, off, endIndex ) ;
			}catch(Exception e){
				e.printStackTrace() ;
				break ;
			}
			if( lBlock == null )
				break ;
			
			off = lBlock.getEnd() ;
			numBlockList.add(lBlock) ;
		}
		if( numBlockList.isEmpty() )
			return null ;
			
		ArrayList<Block<ParsedDimension>> result = new ArrayList<Block<ParsedDimension>>() ;
		String unitKind = null;//ValuesExtractorV1.extractUnitKind(meta) ;
		
		int ub, lb ;
		final int size = numBlockList.size();
		Block<ParsedDimension> prevBlock = null ;
		for( int i = 0 ; i < size ; i++ )
		{
			Block<Double> numBlock = numBlockList.get(i) ;			

			lb = numBlock.getEnd() ;
			ub = ( i == size-1 ) ? endIndex : numBlockList.get(i+1).getStart() ;			
			Block<Unit> unitBlock = lookUnitInTheBeginning( str, lb, ub, unitKind);

			if( unitBlock == null ){
				lb = prevBlock != null ? prevBlock.getEnd() : (i==0) ? startIndex : numBlockList.get(i-1).getEnd() ;
				ub = numBlock.getStart() ;
				unitBlock = lookUnitInTheEnd(str, lb, numBlock.getStart(), unitKind);
			}
			
			if( unitBlock == null ){
				prevBlock = null ;
				continue ;
			}
			
			int start = Math.min( numBlock.getStart(), unitBlock.getStart() ) ;
			int end   = Math.max( numBlock.getEnd(), unitBlock.getEnd() ) ;

			String newComment = getDefaultComment(comment) ;
			ParsedDimension pDim = new ParsedDimension( numBlock.getVal(), unitBlock.getVal(), newComment ) ;
			Block<ParsedDimension> blk = new Block<ParsedDimension>(str, start, end, pDim, Block.BLOCK_KIND_DIMENSION) ;
			result.add(blk) ;
			
			numBlock.putMetaInfo("processed", true ) ;
			numBlock.putMetaInfo("valBlock", blk ) ;
			
			prevBlock = blk ;
		}

		ArrayList<Block<ParsedDimension>> defaultReturnValue = result.isEmpty() ? null : result;
		Unit unit = null ;
		try{
			unit = (Unit) metaInfo.get( "unit" );			
		} finally{
			if( unit == null )				
				return defaultReturnValue ;
		}
		
		
		ArrayList<Block<Double>> queue = new ArrayList<Block<Double>>() ; 
		if( startIndex == 0 ){
			Block<Double> firstBlock = numBlockList.get(0);
			firstBlock.putMetaInfo("position", "firstBlock" ) ;
			queue.add( firstBlock ) ;
		}
		
		if( endIndex == str.length() ) {
			Block<Double> lastBlock = numBlockList.get(size-1);
			lastBlock.putMetaInfo("position", "lastBlock" ) ;
			queue.add( lastBlock ) ;
		}
		
		if( queue.isEmpty() )
			return defaultReturnValue ;
		
		for( Block<Double> numBlock : queue ){
			
			try{
				Boolean processed = numBlock.getMetaInfo("processed", Boolean.class ) ;
				if( processed != null && processed )
					continue ;
			}
			finally{}
			
			//do we have Unit of some other kind associated with the numBlock ?
			Block<Unit> uBlock = lookUnitInTheBeginning(str, numBlock.getEnd(), endIndex, null ) ;
			if( uBlock != null )
				continue ;
			
			String position = numBlock.getMetaInfo( "position", String.class ) ;
			ParsedScalar pc = new ParsedScalar( numBlock.getVal(), "") ;
			Block<ParsedScalar> pcBlock = new Block<ParsedScalar>(str, numBlock.getStart(), numBlock.getEnd(), pc, Block.BLOCK_KIND_SCALAR) ;
			metaInfo.put(position, pcBlock) ;
//			
//			String newComment = getDefaultComment(comment) ;
//			ParsedDimension pDim = new ParsedDimension( numBlock.getVal(), unit, newComment ) ;
//			Block<ParsedDimension> blk = new Block<ParsedDimension>( str, numBlock.getStart(), numBlock.getEnd(), pDim) ;
//			numBlock.putMetaInfo("processed", true ) ;
//			numBlock.putMetaInfo("valBlock", blk ) ;

		}
		return defaultReturnValue ;
		
//		result.clear() ;
//		for( Block<Double> numBlock : numBlockList ){
//			try{
//				Block<ParsedDimension> blk = numBlock.getMetaInfo("valBlock", Block.class ) ;
//				if( blk != null )
//					result.add(blk) ;
//			}finally{}								
//		}		
//		return result ;

	}

}
